# -*- coding: utf-8 -*-
"""
报表数据提供者基础定义。
"""
from __future__ import annotations

from abc import ABC, abstractmethod
from contextlib import contextmanager
from typing import Any, Dict, List

import pymysql

from app.services.data_source_service import DataSourceService


class SafeDict(dict):
    """Safe dict for str.format_map: missing keys return empty string."""

    def __missing__(self, key):
        return ""


class BaseProvider(ABC):
    """数据提供者基类"""

    def __init__(self, params: Dict[str, Any], template_code: str | None = None):
        self.params = params or {}
        self.template_code = template_code

    def get_data_source_configs(
        self, service_type: str | None = None, config_ids: List[int] | None = None
    ) -> List[Dict]:
        """获取数据源配置列表"""
        return DataSourceService.get_configs(
            service_type=service_type, config_ids=config_ids
        )

    @contextmanager
    def get_data_source_connection(self, config_id: int, autocommit: bool = False):
        """获取数据源连接（上下文管理器）"""
        with DataSourceService.get_connection(config_id, autocommit) as conn:
            yield conn

    @contextmanager
    def get_data_source_cursor(self, config_id: int, autocommit: bool = False):
        """获取数据源游标（上下文管理器）"""
        with self.get_data_source_connection(config_id, autocommit) as conn:
            cursor = conn.cursor()
            try:
                yield cursor
            finally:
                cursor.close()

    def create_data_source_connection(
        self, config_id: int, autocommit: bool = False
    ) -> pymysql.Connection:
        """创建数据源连接"""
        return DataSourceService.create_connection(config_id, autocommit)

    @abstractmethod
    def collect(self) -> Dict[str, Any]:
        """收集数据"""

    @abstractmethod
    def generate_summary(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """生成数据摘要"""


